/**
 *  Document   : HotelAndRoomTreatment
 *  Created on : 18 juil. 2008, 01:22:46
 *  Author     : Rivo
 */
package gla.centralhotel.uiweb.treatment;

import com.sun.data.provider.RowKey;
import com.sun.rave.web.ui.appbase.AbstractRequestBean;
import gla.centralhotel.business.IHotelAndRoomManagement;
import gla.centralhotel.exception.HotelRoomNumberException;
import gla.centralhotel.exception.IllegalPeriodException;
import gla.centralhotel.exception.IllegalPriceException;
import gla.centralhotel.exception.NoCurrentRoomException;
import gla.centralhotel.exception.PriceFormatException;
import gla.centralhotel.exception.SubscriptionManagementException;
import gla.centralhotel.exception.TooLongTextException;
import gla.centralhotel.model.Hotel;
import gla.centralhotel.model.Price;
import gla.centralhotel.model.Room;
import gla.centralhotel.model.RoomType;
import gla.centralhotel.model.Zipcode;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.FacesException;
import gla.centralhotel.uiweb.SessionBean;
import gla.centralhotel.uiweb.ApplicationBean;
import gla.centralhotel.uiweb.screens.HotelProperties;
import gla.centralhotel.uiweb.screens.RoomProperties;
import java.util.Date;
import javax.faces.context.FacesContext;

/**
 * <p>Request scope data bean for your application.  Create properties
 *  here to represent data that should be made available across different
 *  pages in the same HTTP request, so that the page bean classes do not
 *  have to be directly linked to each other.</p>
 *
 * <p>An instance of this class will be created for you automatically,
 * the first time your application evaluates a value binding expression
 * or method binding expression that references a managed bean using
 * this class.</p>
 *
 */
public class HotelAndRoomTreatment extends AbstractRequestBean {

    @EJB
    private IHotelAndRoomManagement hotelAndRoomManagement;
    FacesContext context = getFacesContext();
    // <editor-fold defaultstate="collapsed" desc="Managed Component Definition">

    /**
     * <p>Automatically managed component initialization.  <strong>WARNING:</strong>
     * This method is automatically generated, so any user-specified code inserted
     * here is subject to being replaced.</p>
     */
    private void _init() throws Exception {
    }
    // </editor-fold>

    /**
     * <p>Construct a new request data bean instance.</p>
     */
    public HotelAndRoomTreatment() {
    }

    /**
     * <p>This method is called when this bean is initially added to
     * request scope.  Typically, this occurs as a result of evaluating
     * a value binding or method binding expression, which utilizes the
     * managed bean facility to instantiate this bean and store it into
     * request scope.</p>
     * 
     * <p>You may customize this method to allocate resources that are required
     * for the lifetime of the current request.</p>
     */
    @Override
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here

        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("HotelAndRoomTreatment Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e : new FacesException(e);
        }

    // </editor-fold>
    // Perform application initialization that must complete
    // *after* managed components are initialized
    // TODO - add your own initialization code here
    }

    /**
     * <p>This method is called when this bean is removed from
     * request scope.  This occurs automatically when the corresponding
     * HTTP response has been completed and sent to the client.</p>
     * 
     * <p>You may customize this method to clean up resources allocated
     * during the execution of the <code>init()</code> method, or
     * at any later time during the lifetime of the request.</p>
     */
    @Override
    public void destroy() {
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected SessionBean getSessionBean() {
        return (SessionBean) getBean("SessionBean");
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected ApplicationBean getApplicationBean() {
        return (ApplicationBean) getBean("ApplicationBean");
    }

    /**
     * Ajoute un hotel ou met à jour l'hotel édité!!
     * @param form
     * @throws gla.centralhotel.exception.SubscriptionManagementException
     */
    public void saveHotelInfo(HotelProperties form) throws SubscriptionManagementException, TooLongTextException {
        Hotel htl = getSessionBean().getCurrentHotel();
        if (htl != null) {// update hotel

            try {
                try {
                    htl = hotelAndRoomManagement.saveHotelSubscription(initHotelToSave(htl, form));
                } catch (TooLongTextException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new TooLongTextException("Description ou service trop long 255 caractères max !!");
                }
                getSessionBean().setCurrentHotel(htl);
            } catch (SubscriptionManagementException ex) {
                throw new SubscriptionManagementException("Erreur de mise à jour l'hotel n'a pas de manager");
            }
        } else {// ajoute un hotel

            htl = new Hotel();
            htl.setRefManager(getSessionBean().getCurrentManager());
            try {
                try {
                    htl = hotelAndRoomManagement.saveHotelSubscription(initHotelToSave(htl, form));
                } catch (TooLongTextException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new TooLongTextException("Description ou service trop long 255 caractères max !!");
                }
                getSessionBean().setCurrentHotel(htl);
            } catch (SubscriptionManagementException ex) {
                throw new SubscriptionManagementException("Erreur ajout hotel, manager manquant!!");
            }
        }
    }

    /**
     * initialise les propriétés de l'hotel depuis le form
     * @param htl
     * @param form
     * @return
     */
    private Hotel initHotelToSave(Hotel htl, HotelProperties form) throws TooLongTextException {
        // update hotel
        htl.setName(form.getTbHotelName().getValueAsString(context));
        htl.setAddress1(form.getTbAddr1().getValueAsString(context));
        htl.setAddress2(form.getTbAddr2().getValueAsString(context));
        htl.setAddress3(form.getTbAddr3().getValueAsString(context));
        String desc = form.getTaDescription().getValueAsString(context);
        String sce = form.getTaSrvEquip().getValueAsString(context);
        htl.setDescription(desc);
        htl.setServicesEquipments(sce);
        if (desc.length() > 255 || sce.length() > 255) {
            throw new TooLongTextException("Description ou service trop long 255 caractères max !!");
        }
        Zipcode z = new Zipcode(Integer.valueOf((String) form.getDdlZipcode().getSelected()));
        htl.setRefZipcode(z);
        return htl;
    }

    public void saveRoomInfo(RoomProperties form) throws HotelRoomNumberException {
        if (getSessionBean().getCurrentRoom() != null) {
            getSessionBean().getCurrentRoom().setNumber(form.getTbRoomNumber().getValueAsString(context));
            RoomType type = new RoomType(Integer.valueOf((String) form.getDdlRoomType().getSelected()));
            getSessionBean().getCurrentRoom().setRefRoomType(type);
            try {
                Room tmp = hotelAndRoomManagement.addRoomToHotel(getSessionBean().getCurrentRoom());
                getSessionBean().setCurrentRoom(tmp);
            } catch (HotelRoomNumberException e) {
                throw new HotelRoomNumberException("ERREUR d'enregistrement !");
            }
        } else {
            Room rm = new Room();
            rm.setHotelName(getSessionBean().getCurrentHotel().getName());
            rm.setNumber(form.getTbRoomNumber().getValueAsString(context));
            rm.setRefHotel(getSessionBean().getCurrentHotel());
            RoomType type = new RoomType(Integer.valueOf((String) form.getDdlRoomType().getSelected()));
            rm.setRefRoomType(type);

            try {
                Room tmp = hotelAndRoomManagement.addRoomToHotel(rm);
                getSessionBean().setCurrentRoom(tmp);
            } catch (HotelRoomNumberException ex) {
                throw new HotelRoomNumberException("Le numéro de la chambre existe déjà !");
            }
        }
    }

    public void savePriceForCurrentRoom(RoomProperties form) throws NoCurrentRoomException, IllegalPeriodException, IllegalPriceException, PriceFormatException {
        if (getSessionBean().getCurrentRoom() != null) {
            String price = form.getTbRoomPrice().getValueAsString(context);
            String tmpP;
            if (price.contains(",")) {
                tmpP = price.replace(",", ".");
                price = tmpP;
                if (tmpP.split(".").length > 2) {
                    throw new PriceFormatException("Format du prix incoorect!");
                }
                Float priceReal = Float.valueOf(price);
                Date start = form.getTbStartPeriod().getSelectedDate();
                Date end = form.getTbEndPeriod().getSelectedDate();
                try {
                    Price ret = hotelAndRoomManagement.setPriceToRoom(getSessionBean().getCurrentRoom(), start, end, priceReal);
                    Price[] tmp = new Price[getSessionBean().getPricePerRoom().length + 1];
                    tmp = getSessionBean().getPricePerRoom();
                    tmp[tmp.length] = ret;
                    getSessionBean().setPricePerRoom(tmp);
                } catch (IllegalPriceException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new IllegalPriceException("Erreur grave il y a plusieurs prix " +
                            "sur une même période pour la même chambre");
                } catch (IllegalPeriodException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new IllegalPeriodException("Il y a déjà un prix sur cette période !");
                }
            } else {
                Float priceReal = Float.valueOf(price);
                Date start = form.getTbStartPeriod().getSelectedDate();
                Date end = form.getTbEndPeriod().getSelectedDate();
                try {
                    Price ret = hotelAndRoomManagement.setPriceToRoom(getSessionBean().getCurrentRoom(), start, end, priceReal);
                    Price[] tmp = new Price[getSessionBean().getPricePerRoom().length + 1];
                    tmp = getSessionBean().getPricePerRoom();
                    tmp[tmp.length] = ret;
                    getSessionBean().setPricePerRoom(tmp);
                } catch (IllegalPriceException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new IllegalPriceException("Erreur grave il y a plusieurs prix " +
                            "sur une même période pour la même chambre");
                } catch (IllegalPeriodException ex) {
                    Logger.getLogger(HotelAndRoomTreatment.class.getName()).log(Level.SEVERE, null, ex);
                    throw new IllegalPeriodException("Il y a déjà un prix sur cette période !");
                }
            }
        } else {
            throw new NoCurrentRoomException("Aucune chambre éditée !");
        }
    }

    public void deletePrice(RoomProperties form) {
        RowKey rk = form.getTableRowRoomPrices().getRowKey();
        Price tmp = getSessionBean().getRoomPricesList()[Integer.parseInt(rk.getRowId())];
        hotelAndRoomManagement.deletePrice(tmp);
    }
}
